<?php

namespace App\Services\Third;

use App\Exceptions\ExceptionHelper;
use App\Http\Request;
use Log;

class GaoDe extends Base
{

    private $host = 'http://restapi.amap.com';
    private $port = 80;

    const GEOCODE    = '/v3/geocode/geo';
    const RE_GEOCODE = '/v3/geocode/regeo';
    const DISTANCE   = '/v3/distance';

    private $key;

    public function __construct($key)
    {
        $this->key = $key;
        parent::__construct($this->host, $this->port);
    }

    /**
     * 地理编码
     * @param $text
     * @return array|mixed|string
     * @throws \Throwable
     */
    public function geocodeGeo($text)
    {
        try {
            $param        = [
                'address' => $text,
                'output'  => 'json'
            ];
            $address_json = $this->request(self::GEOCODE, $param);
            if ($address_json['status'] != 1) {
                throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '高德解析失败:' . $address_json['info']);
            }
            $geoCodes = $address_json['geocodes'];
            if (count($geoCodes) == 0) {
                throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '高德解析失败');
            }
            $first = $geoCodes[0];
            $arr   = explode(",", $first['location']);
            return [
                'province'  => is_string($first['province']) ? str_replace(['省', '市', '特别行政区', '维吾尔自治区', '自治区', '壮族自治区', '回族'], '', $first['province']) : '',
                'city'      => is_string($first['city']) ? $first['city'] : '',
                'district'  => is_string($first['district']) ? $first['district'] : '',
                'address'   => is_string($first['formatted_address']) ? $first['formatted_address'] : '',
                'longitude' => $arr[0],
                'latitude'  => $arr[1]
            ];
        } catch (\Throwable $e) {
            Log::info($e->getMessage(), $e->getTrace());
            throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '地址有误，请检查后再试');
        }
    }

    /**
     * @param $lat
     * @param $lng
     * @return array|mixed
     * @throws \Throwable
     * @name: geocodeReGeo
     * @author: zhuxuesong
     * @datetime: 2021-08-30 16:05
     */
    public function geocodeReGeo($lat, $lng)
    {
        try {
            $param        = [
                'location' => sprintf('%s,%s', $lng, $lat),
                'output'   => 'json',
            ];
            $address_json = $this->request(self::RE_GEOCODE, $param);
            if ($address_json['status'] != 1) {
                throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '高德解析失败:' . $address_json['info']);
            }
            if (!isset($address_json['regeocode'])) {
                throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '高德解析失败');
            }
            return $address_json['regeocode'];
        } catch (\Throwable $e) {
            Log::info($e);
            throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '经纬度有误，请检查后再试');
        }
    }

    /**
     * 路径规划
     * @param $startLat
     * @param $startLng
     * @param $endLat
     * @param $endLng
     * @return int|mixed|string
     * @throws \Throwable
     * @name:getDistance
     * @author: lisa
     * @datetime: 2021/10/26 15:46
     */
    public function getDistance($startLat, $startLng, $endLat, $endLng)
    {
        try {
            $param        = [
                'origins'     => "{$startLng},{$startLat}", // 起始经纬度
                'destination' => "{$endLng},{$endLat}", // 终点经纬
                'type'        => 1, // 驾车导航距离（仅支持国内坐标）
                'output'      => 'JSON', // 返回数据格式类型
            ];
            $address_json = $this->request(self::DISTANCE, $param);
            if ($address_json['status'] != 1) {
                throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '高德解析失败:' . $address_json['info']);
            }
            if (!isset($address_json['results'])) {
                throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '高德解析失败');
            }
            return $address_json['results'][0]['distance'] ?? 0;
        } catch (\Throwable $e) {
            Log::info($e->getMessage(), $e->getTrace());
            throw ExceptionHelper::getInstance(ExceptionHelper::GOO_DE_ERROR, '路径有误，请检查后重试');
        }
    }

    /**
     * @param string $uri
     * @param array $params
     * @param string $method
     * @param bool $isJson
     * @return array|mixed|string
     * @throws \Throwable
     */
    public function request($uri, $params = [], $method = Request::GET_METHOD, $isJson = !Request::IS_JSON)
    {
        $params['key'] = $this->key;
        return parent::request($uri, $params, $method, $isJson); // Change the autogenerated stub
    }
}
